package com.fan.gofast.compent;


import cn.hutool.core.exceptions.ExceptionUtil;
import com.fan.gofast.constant.ResultEnum;
import com.fan.gofast.dtos.BaseResponse;
import com.fan.gofast.util.ResponseUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@RestControllerAdvice
@Slf4j
@ResponseBody
public class GlobalDefaultExceptionHandler {



    @ExceptionHandler(Exception.class)
    public BaseResponse<?> handleException(Exception ex) {
        log.info("system exception -> ", ex);
        return ResponseUtils.error(ResultEnum.SYSTEM_EXCEPTION);
    }

    @ExceptionHandler(BindException.class)
    @ResponseBody
    public <T> BaseResponse<T> handleBindException(HttpServletRequest request, BindException e) {
        log.error("handleBindException error:{}", ExceptionUtil.getMessage(e));
        return handle(e.getBindingResult());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public <T> BaseResponse<T> handleMethodArgumentNotValidException(HttpServletRequest request,
                                                                     MethodArgumentNotValidException e) {
        log.error("handleMethodArgumentNotValidException error:{}", ExceptionUtil.getMessage(e));
        return handle(e.getBindingResult());
    }


    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public <T> BaseResponse<T> handleBindException(BusinessException e) {
        BaseResponse response = new BaseResponse();
        response.setCode(e.getErrorCode());
        response.setMessage(e.getErrorMessage());
        return response;
    }

    private <T> BaseResponse<T> handle(BindingResult bindingResult) {
        StringBuffer errorMsg = new StringBuffer();
        List<ObjectError> errors = bindingResult.getAllErrors();
        errors.forEach(error -> errorMsg.append(error.getDefaultMessage()).append(";"));
        return ResponseUtils.error(ResultEnum.PARAM_ERROR.code, errorMsg.toString());
    }
}
